// DBDeployer - The MySQL Sandbox
// Copyright © 2006-2020 Giuseppe Maxia
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"
	"path"
	"regexp"

	"github.com/spf13/cobra"

	"github.com/datacharmer/dbdeployer/common"
	"github.com/datacharmer/dbdeployer/defaults"
	"github.com/datacharmer/dbdeployer/globals"
)

var defaultsExecutableTemplate = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using {{.TemplateName}} on {{.DateTime}}

[ -z "$SANDBOX_HOME" ] && export SANDBOX_HOME={{.SandboxHome}}

cd $SANDBOX_HOME

[ -z "$default_sandbox" ] && default_sandbox="{{.DefaultSandbox}}"

if [ -z "$default_sandbox" ]
then
    echo "default sandbox not defined in $0"
    exit 1
fi

if [ ! -d $default_sandbox ]
then
    echo "default sandbox $PWD/$default_sandbox does not exist"
    exit 1
fi

cd $default_sandbox

command=$1
if [ -z "$command" ]
then
	echo "syntax: $0 sandbox_command [command arguments]"
    exit 1
fi

if [ "$command" != "ls" -a ! -x "$command" ]
then
	echo "command '$command' not found in $PWD"
	if [ -x "${command}_all" ]
    then
        echo "Default sandbox '$default_sandbox' is not a single sandbox"
        echo "Try '${command}_all' instead"
    fi
	exit 1
fi

has_dot=$(echo "$1" | grep '^\./')
if [ -n "$has_dot" -o "$command" == "ls" ]
then
    "$@"
else
    ./"$@"
fi
`

func adminDefaultSandbox(cmd *cobra.Command, sandboxName string, setNew bool) error {

	sandboxDir, err := getAbsolutePathFromFlag(cmd, "sandbox-home")
	if err != nil {
		common.Exitf(1, "error getting absolute path for sandbox home: %s", err)
	}
	defaultExec, _ := cmd.Flags().GetString(globals.DefaultSandboxExecutable)
	defaultsExecutable := path.Join(sandboxDir, defaultExec)
	sandboxFullName := path.Join(sandboxDir, sandboxName)
	sandboxDefaultMarker := path.Join(sandboxFullName, "is_default")

	if !setNew {
		if common.ExecExists(defaultsExecutable) {

			execText, err := common.SlurpAsString(defaultsExecutable)
			if err != nil {
				return fmt.Errorf("error reading %s: %s", defaultsExecutable, err)
			}
			defRe := regexp.MustCompile(`default_sandbox="([^"]+)"`)
			captureList := defRe.FindAllStringSubmatch(execText, -1)
			if len(captureList) == 0 || len(captureList[0]) == 0 {
				return fmt.Errorf("error extracting sandbox name from %s", defaultsExecutable)
			}

			err = os.Remove(defaultsExecutable)
			if err != nil {
				return fmt.Errorf("error removing %s: %s", defaultsExecutable, err)
			}

			sandboxDefaultMarker = path.Join(sandboxDir, captureList[0][1], "is_default")

			err = os.Remove(sandboxDefaultMarker)
			if err != nil {
				return fmt.Errorf("error removing %s: %s", sandboxDefaultMarker, err)
			}
			fmt.Printf("%s removed\n", sandboxDefaultMarker)
			fmt.Printf("%s removed\n", defaultsExecutable)
		} else {
			fmt.Printf("no '%s' executable found in %s\n", defaults.Defaults().DefaultSandboxExecutable, sandboxDir)
		}

		return nil
	}

	if !common.DirExists(sandboxFullName) {
		return fmt.Errorf("sandbox %s not found", sandboxName)
	}
	data := common.StringMap{
		"ShellPath":      defaults.Defaults().ShellPath,
		"Copyright":      globals.ShellScriptCopyright,
		"AppVersion":     common.VersionDef,
		"TemplateName":   "default_sandbox",
		"SandboxHome":    sandboxDir,
		"DefaultSandbox": sandboxName,
	}
	filledTemplate, err := common.SafeTemplateFill("default_sandbox", defaultsExecutableTemplate, data)
	if err != nil {
		return err
	}
	err = common.WriteString(filledTemplate, defaultsExecutable)
	if err != nil {
		return err
	}
	fmt.Printf("%s created with sandbox %s\n", defaultsExecutable, sandboxName)
	err = os.Chmod(defaultsExecutable, globals.ExecutableFileAttr)
	if err != nil {
		return err
	}

	err = common.WriteString(defaultsExecutable, sandboxDefaultMarker)
	if err != nil {
		return err
	}
	return nil
}
